package stream;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.DoubleSummaryStatistics;
import java.util.List;
import java.util.Random;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * 测试Stream
 * @author ben
 * @date 2022-01-17 19:54:30 CST
 */
public class TestStream {

	private static Consumer<Object> cs = System.out::println;

	public static void main(String[] args) {
//		test1();
		
		test2();
	}

	/**
	 * 测试1
	 * @author ben
	 * @date 2022-01-17 20:23:34 CST
	 */
	private static void test1() {
		List<Integer> il = new ArrayList<Integer>();
		cs.accept(il);
		
		IntStream is = IntStream.range(0, 10);
		is.forEach(e->{
			il.add(e);
		});
		
		cs.accept(il);
		
		cs.accept("forEach:输出每个元素");
		il.forEach(e->{
			cs.accept(e);
		});
		
		cs.accept("filter: 输出大于5的元素");
		il.stream().filter(e->e>5).forEach(e->{
			cs.accept(e);
		});
		
		cs.accept("filter: count");
		List<String> strs = Arrays.asList("a", "b", "", "cd", "D", "e", "b", "a", "a");
		cs.accept(strs);
		long cnt = strs.stream().count();
		cs.accept("cnt 1=" + cnt);
		cnt = strs.stream().filter(e->{return e.equals("a");}).count();
		cs.accept("cnt 2(\"a\")=" + cnt);
		cnt = strs.stream().filter(e->e.isEmpty()).count();
		cs.accept("cnt 3(\"\")=" + cnt);
		
		cs.accept("map: ");
		List<Integer> numbers = Arrays.asList(19, 57, 3, 200, 502);
		cs.accept(numbers);
		List<Integer> squareNumbers = numbers.stream().map(e->e*e).distinct().collect(Collectors.toList());
		cs.accept(squareNumbers);
		
		cs.accept("limit: 随机数");
		Random random = new Random();
		random.ints().limit(6).forEach(System.out::println);
		
		cs.accept("boxed: ");
		IntStream is66 = random.ints().limit(7);
		cs.accept(is66);
		// stream has already been operated upon or closed
//		is66.forEach(System.out::println);
		List<Integer> is66List = is66.boxed().collect(Collectors.toList());
		cs.accept(is66List);
		
		cs.accept("sorted: ");
		// Stream size exceeds max array size
//		random.ints().sorted().limit(10).forEach(System.out::println);
		// ok 先 limit，再 sorted
		random.ints().limit(10).sorted().forEach(System.out::println);
	}

	/**
	 * 测试2
	 * @author ben
	 * @date 2022-01-17 20:34:43 CST
	 */
	private static void test2() {
		cs.accept("parallel:");
		Random rand = new Random();
		List<Integer> il1 = rand.ints().parallel().limit(10).boxed().collect(Collectors.toList());
		cs.accept("il1=" + il1);
		
		cs.accept("parallelStream:");
//		List<Integer> il2 = il1.parallelStream().filter(e->e>0).collect(Collectors.toList());
//		List<Integer> il2 = il1.parallelStream().filter(e->e>0).sorted().collect(Collectors.toList());
		List<Integer> il2 = il1.parallelStream().filter(e->e>0).sorted().unordered().collect(Collectors.toList());
		cs.accept("il2=" + il2);
		
		cs.accept("Collectors:");
		List<String> strs1 = Arrays.asList("a", "b", "apple", "pear", "--");
		cs.accept(strs1);
		String mergedStrs1 = strs1.stream().filter(str -> !str.isEmpty()).collect(Collectors.joining("; "));
		String mergedStrs2 = strs1.parallelStream().filter(str -> !str.isEmpty()).collect(Collectors.joining("; "));
		cs.accept(mergedStrs1);
		cs.accept(mergedStrs2);
		
		cs.accept("统计：");
		List<Double> dl1 = Arrays.asList(1.1, 2.2, 3.3, 5.5, 99.99, 6.6, 89.8);
		
		DoubleSummaryStatistics stats = dl1.stream().mapToDouble(x->x).summaryStatistics();
		cs.accept("stats=" + stats);
		cs.accept("stats.count=" + stats.getCount());
		cs.accept("stats.max=" + stats.getMax());
		cs.accept("stats.min=" + stats.getMin());
		cs.accept("stats.sum=" + stats.getSum());
		cs.accept("stats.average=" + stats.getAverage());
		
	}
}
